/*
 * @Description:
 * @Version: 1.0
 * @Autor: lzc
 * @Date: 2021-09-15 15:38:07
 * @LastEditors: lzc
 * @LastEditTime: 2021-09-18 15:53:11
 */

// NOTE: RT-Thread操作系统如果开启Shell组件需要提前退出FinSH模式
/*
 *  rt_thread_t FinSH_Task;
    // 先退出FinSH模式
    FinSH_Task = rt_thread_find(FINSH_THREAD_NAME);
    rt_thread_suspend(FinSH_Task);
 */
#include "m1130_utility_usart.h"
#include "command_parse.h"
#include "upacker.h"
#include "shell.h"
#include "rtdef.h"
#include "rtthread.h"


#define COM_TYPE_HEX            2
#define COM_TYPE_STR            3

upacker_inst msg_packer;

static char SoftVer_date_buf[12] = { 0 };
static const char COMPILE_DATE[] = __DATE__;    //Year,Month,Date
static const char COMPILE_TIME[] = __TIME__;    //hour,min,sec

static const char s_cMonth[]   = "JanFebMarAprMayJunJulAugSepOctNovDec";
static void HEX_Arg_Send(uint8_t *d, uint16_t size);


void handle_cb(uint16_t command, uint8_t *d, uint16_t size);
void uart_send( uint8_t *d, uint16_t size);
// 如果是RT-Thread 并且带串口驱动的情况
#if USING_RT_DEVICE_RX

typedef struct
{
#define UART_RX_BUFFER_SIZE 256
    char rx_buf[UART_RX_BUFFER_SIZE];
    volatile int rxlen;
    volatile int rx_flag;
    volatile int rx_ptr;
} UartRecvBufferStruct;

UartRecvBufferStruct Uart1_Recv;
void UartRecvStructInit(UartRecvBufferStruct Uart_Recv)
{
    Uart_Recv.rxlen = 0;
    Uart_Recv.rx_flag = 0;
    Uart_Recv.rx_ptr = 0;

    memset(Uart_Recv.rx_buf, 0, UART_RX_BUFFER_SIZE);
}

/* 用于接收消息的信号量 */
static struct rt_semaphore rx_sem;
static struct rt_semaphore uart_status_sem;
static rt_device_t serial;
static rt_tick_t Uart_Tick_TimeOut_Count = 0;
/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    Uart_Tick_TimeOut_Count = rt_tick_get();
    rt_sem_release(&uart_status_sem);
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

static void serial_thread_entry(void *parameter)
{
    char ch;

    while (1)
    {
        // 检测FinSH的状态如果是回显则关闭回显
        if (finsh_get_echo() == 0x01)
        {
            finsh_set_echo(0);      // 关闭回显
            finsh_set_prompt("\0"); // 关闭MSH显示
        }
        /* 从串口读取一个字节的数据，没有读取到则等待接收信号量 */
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            /* 阻塞等待接收信号量，等到信号量后再次读取数据 */
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
            rt_sem_take(&uart_status_sem, RT_WAITING_FOREVER);
        }
        Uart1_Recv.rx_buf[Uart1_Recv.rx_ptr] = ch;
        Uart1_Recv.rx_ptr++;
        Uart1_Recv.rx_flag = 0;
    }
}

/**
 * @function: back_FinSH
 * @brief:
 * @param {*}
 * @return {*}
 * @author: lzc
 */

static char sys_FinSH_Status = 0;

static int back_FinSH(void)
{
    rt_thread_t FinSH_Task;
    FinSH_Task = rt_thread_find(FINSH_THREAD_NAME);
    sys_FinSH_Status = 1;
    rt_thread_resume(FinSH_Task); return 0;
}

/**
 * @function: exit_FinSH
 * @brief:
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static int exit_FinSH(void)
{
    rt_thread_t FinSH_Task;
    FinSH_Task = rt_thread_find(FINSH_THREAD_NAME);
    sys_FinSH_Status = 0;
    rt_thread_suspend(FinSH_Task); return 0;
}
MSH_CMD_EXPORT(exit_FinSH, Exit the FinSH Mode);

static void timer_thread_entry(void *parameter)
{
    rt_err_t result;
    sys_FinSH_Status = 0;
    while (1)
    {
        if (!sys_FinSH_Status) // 没有FinSH
        {
            // 接收完成
            if (rt_tick_get() - Uart_Tick_TimeOut_Count >= 100 && Uart1_Recv.rx_flag == 0)
            {
                Uart1_Recv.rxlen = Uart1_Recv.rx_ptr;
                Uart1_Recv.rx_ptr = 0;
                Uart1_Recv.rx_flag = 1;
                for (int i = 0; i < Uart1_Recv.rxlen; i++)
                {
                    // rt_kprintf(" Uart1_Recv.rx_buf[%d] = %x\r\n",i,Uart1_Recv.rx_buf[i]);
                }
            }
            if (  Uart1_Recv.rx_flag == 1 )
            {
                /* 从消息队列中读取消息*/
                // 如果是16进制
                if (Uart1_Recv.rx_buf[0] == 0xA5 && Uart1_Recv.rx_buf[1] == 0x5A )
                {
                    result = COM_TYPE_HEX;
                }
                // 如果是字符串
                else if (Uart1_Recv.rx_buf[0] != 0x00)
                    result = COM_TYPE_STR;
                else
                    result = RT_ERROR;
                // 16进制解析
                if (result == COM_TYPE_HEX)
                {
                    //丢到packer解析，成功了调用callback
                    upacker_unpack(&msg_packer, (uint8_t *)Uart1_Recv.rx_buf, Uart1_Recv.rxlen);
                    UartRecvStructInit(Uart1_Recv);
                }
                // 字符串解析
                else if (result == COM_TYPE_STR)
                {
                    if (strcmp(Uart1_Recv.rx_buf, "back_FinSH\r\n") == 0)
                    {
                        back_FinSH();
                        UartRecvStructInit(Uart1_Recv);
                    }
                    else
                    {
                        // TODO: 开始解析字符串
                        communicate_parse((const char *)Uart1_Recv.rx_buf);
                        UartRecvStructInit(Uart1_Recv);
                    }
                }
                rt_sem_take(&uart_status_sem, RT_WAITING_FOREVER);
            }
            rt_thread_mdelay(10);
        }
    }
}
static void HEX_Arg_Send(uint8_t *d, uint16_t size)
{
    rt_device_write(serial, 0, d, size);
}

int my_uart_main(void)
{
    rt_err_t ret = RT_EOK;

    UartRecvStructInit(Uart1_Recv);
    /* 查找系统中的串口设备 */
    serial = rt_device_find("uart1");
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", "uart2");
        return RT_ERROR;
    }
    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    rt_sem_init(&uart_status_sem, "uart_status_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);
    // 初始化
    upacker_init(&msg_packer, handle_cb, uart_send);
    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }
    rt_thread_t timer = rt_thread_create("timer", timer_thread_entry, RT_NULL, 1024, 24, 10);
    /* 创建成功则启动线程 */
    if (timer != RT_NULL)
    {
        rt_thread_startup(timer);
    }
    else
    {
        ret = RT_ERROR;
    }

    return ret;
}
INIT_APP_EXPORT(my_uart_main);

#else
// 如果是不带操作系统则将主逻辑放在main函数中进行轮询
// 如果有操作系统则将对应接口对接完毕之后，新建线程
// NOTE: 需要自己实现的接口（HEX）
static void HEX_Arg_Send(uint8_t *d, uint16_t size)
{
    int i = 0;
    for ( i = 0; i < size; i++)
    {
        UART_SendData(UART1, d[i]);
        /* Loop until the end of transmission */
        while (UART_GetFlagStatus(UART1, UART_FLAG_TXFE) == RESET)
        {}
    }
}
// NOTE: 其他主逻辑参照USING_RT_DEVICE_RX
#endif
/**
 * @function: my_putstr
 * @brief:
 * @param {constchar} *str
 * @return {*}
 * @author: lzc
 */
// NOTE: 需要自己实现的接口（STR）
void my_putstr(const char *str, ...)
{
    rt_kprintf(str);
}

/**
  * @brief  convert __DATE__ to yymmdd
  * @param  const char* p_str,Pre-Processing __DATE__
  *         data as "Aug 27 2013" "Aug  1 2013"
  * @param  char* yymmdd,lenght 3 Bytes for year,month,day
  * @retval None
  */
static void getYYMMDDFromStr(const char *p_str, char *yymmdd)
{
    char month = 0;
    char lenght = strlen(p_str);

    if (lenght != 11)
    {
        return;
    }

    for (month = 0; month < 12; month++)
    {
        if (0 == memcmp(&s_cMonth[month * 3], p_str, 3))
        {
            month++;
            break;
        }
    }

    *yymmdd++ = (p_str[9] - '0') * 10 + (p_str[10] - '0');
    *yymmdd++ = month;
    if ((p_str[4] < '0') || (p_str[4] > '3'))//over 01~31
    {
        *yymmdd = p_str[5] - '0';
    }
    else
    {
        *yymmdd = (p_str[4] - '0') * 10 + (p_str[5] - '0');
    }
}

/**
 * @function: idn
 * @brief: 获取型号
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static void my_idn(void)
{
    MSG_OUTPUT("FHP12\n");

}

/**
 * @function: rst
 * @brief: 复位
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static void my_rst(void)
{
    MSG_OUTPUT("ok");
}


/**
 * @function: Get_YY_MM_DD_From_Str
 * @brief: 获取日期时间数据
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static void Get_YY_MM_DD_From_Str(void)
{
    getYYMMDDFromStr(COMPILE_DATE, (char *)&SoftVer_date_buf[2]);
}

/**
 * @function: *ver
 * @brief: 获取版本
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static void my_ver(void)
{
    // DONE: 完善时间戳
    char year[10], month[10], day[10] = {0};
    MSG_OUTPUT("SoftVer: ");
    MSG_OUTPUT(" ");
    // 合成数据
    Get_YY_MM_DD_From_Str();

    sprintf(year, "%d", SoftVer_date_buf[2]);
    sprintf(month, "%d", SoftVer_date_buf[3]);
    sprintf(day, "%d", SoftVer_date_buf[4]);
    // 输出
    MSG_OUTPUT("20");
    MSG_OUTPUT(year);
    MSG_OUTPUT("-");
    MSG_OUTPUT(month);
    MSG_OUTPUT("-");
    MSG_OUTPUT(day);
    MSG_OUTPUT("|");
    MSG_OUTPUT(COMPILE_TIME);
    MSG_OUTPUT("\n");

    MSG_OUTPUT("HardVer: ");
    MSG_OUTPUT(" ");
    MSG_OUTPUT("\n");
}

/**
 * @function: get_Program_Time
 * @brief:获得编译时间
 * @param {char} *buf
 * @return {*}
 * @author: lzc
 */
char *get_Program_Time(char *buf)
{
    char year[10], month[10], day[10] = {0};
    // 合成数据
    Get_YY_MM_DD_From_Str();

    sprintf(year, "%d", SoftVer_date_buf[2]);
    sprintf(month, "%d", SoftVer_date_buf[3]);
    sprintf(day, "%d", SoftVer_date_buf[4]);

    strcat(buf, "20");
    strcat(buf, year);
    strcat(buf, "-");
    strcat(buf, month);
    strcat(buf, "-");
    strcat(buf, day);
    strcat(buf, "-");
    strcat(buf, COMPILE_TIME);
    return buf;
}

unsigned char help(void)
{
    MSG_OUTPUT(" hello\n");
    return 0;
}

/********************************************************************************************/
/********************************************************************************************/
/*************************************字符串方法1通讯协议*************************************/
/****************************************Ver 1.0.0*******************************************/
/********************************************************************************************/
/********************************************************************************************/
///// 使用示例：
/////  1.在命令列表中增加指令 共三处
/////  2.在空白函数中完善代码
/**
 * @function:
 * @brief:
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_idn_fun(Cmd_Info_Type x)
{
    my_idn();
    return 0;
}

/**
 * @function:
 * @brief:
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_ver_fun(Cmd_Info_Type x)
{
    my_ver();
    return 0;
}

/**
 * @function: msg_rst_fun
 * @brief: 复位
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_rst_fun(Cmd_Info_Type x)
{
    my_rst();
    return 0;
}

//////////////////////////////////////////读取命令/////////////////////////////////////////////

/**
 * @function: msg_get_wavelength_fun
 * @brief: 获取波长
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_get_wavelength_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_get_power_fun
 * @brief: 获取功率
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_get_power_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_get_history_fun
 * @brief: 获取历史记录
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_get_history_fun(Cmd_Info_Type x)
{
    return 0;
}


//////////////////////////////////////////设置命令/////////////////////////////////////////////
/**
 * @function: msg_set_wavelength_fun
 * @brief: 设置波长
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_wavelength_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_set_power_fun
 * @brief: 设置 整偏
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_power_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_set_linear_reset_fun
 * @brief: 线性清除
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_linear_reset_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_set_coeff_reset_fun
 * @brief: 整偏清除
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_coeff_reset_fun(Cmd_Info_Type x)
{
    return 0;
}
/**
 * @function: msg_set_switch_fun
 * @brief: 设置光开关
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_switch_fun(Cmd_Info_Type x)
{
    return 0;
}


/**
 * @function: msg_set_idn_fun
 * @brief:保存序列号和产品名称
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_idn_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_set_btname_fun
 * @brief: 设置蓝牙名称
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_set_btname_fun(Cmd_Info_Type x)
{
    return 0;
}


//////////////////////////////////////////校准命令/////////////////////////////////////////////

/**
 * @function: msg_cal_start_fun
 * @brief: 开始校准
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_cal_start_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_cal_stop_fun
 * @brief: 停止校准
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_cal_stop_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_cal_save_fun
 * @brief: 保存校准值
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_cal_save_fun(Cmd_Info_Type x)
{
    return 0;
}
//
/**
 * @function: msg_cal_level_fun
 * @brief: 档位
 * @param {Cmd_Info_Type} x
 * @return {*}
 * @author: lzc
 */
uint8_t msg_cal_level_fun(Cmd_Info_Type x)
{
    return 0;
}
/**
 * @brief 校准点,具有确定性
 * @param
 * @return
 */
uint8_t msg_cal_point_power_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_sys_upgrade_fun
 * @brief:系统升级
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_sys_upgrade_fun(Cmd_Info_Type x)
{
    return 0;
}

/**
 * @function: msg_sys_screen_fun
 * @brief:
 * @param {*}
 * @return {*}
 * @author: lzc
 */
uint8_t msg_sys_screen_fun(Cmd_Info_Type x)
{
    return 0;
}


/********************************************************************************************/
/********************************************************************************************/
/*************************************新版本 HEX 通讯协议*************************************/
/****************************************Ver 1.0.0*******************************************/
/********************************************************************************************/
/********************************************************************************************/
///// 使用示例：
/////  1. 初始化 ：upacker_init(&msg_packer, handle_cb, uart_send);
/////  2. 丢到packer解析，成功了调用callback
//          upacker_unpack(&msg_packer, (uint8_t *)Uart1_Recv.rx_buf, Uart1_Recv.rxlen);
/////  3.在回调中完善代码
///

/**
  * @brief  串口发送接口
  * @note
  * @param  *d:
  * @param  size:
  * @retval None
  */
void uart_send( uint8_t *d, uint16_t size)
{
    HEX_Arg_Send(d, size);
}
/**
  * @brief  消息解析回调
  * @note
  * @param  *d:
  * @param  size:
  * @retval None
  */
void handle_cb(uint16_t command, uint8_t *d, uint16_t size)
{
    uint8_t Buffer[MAX_PACK_SIZE] = { 0 };
    //接收到payload
#if UPACKER_DEBUG
    rt_kprintf("pack len is %d,pack command is %d\n", size, command);
#endif
    switch (command)
    {
    case 0x0000:
        Buffer[0] = 0xff;
        Buffer[1] = 0xfe;
        // Buffer 的数据实际为发送的数据 后面的Size是 Buffer中数据的长度
        upacker_pack(&msg_packer, command, Buffer, 2);
        break;
    case 0xffff:
        // Buffer 的数据实际为发送的数据 后面的Size是 Buffer中数据的长度
        upacker_pack(&msg_packer, command, Buffer, 0);
        break;
    default:
        break;
    }
}


/********************************************************************************************/
/********************************************************************************************/
/*************************************字符串方法2通讯协议*************************************/
/****************************************Ver 1.0.0*******************************************/
/********************************************************************************************/
/********************************************************************************************/
/******************************************user code*****************************************/
///// 使用示例：
/////  1. 完善函数
/////  2. 每个函数最下面加上IMPORT_MSG_FUN(xxx);
/////  3. 如果被优化建议使用旧版本字符串指令
//////////////////////////////////////////通用命令/////////////////////////////////////////////
/**
 * @function: idn
 * @description: 查询仪表型号
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t idn(myCmd_Info_Type info)
{
    my_idn();
    return MS_EOK;
}
IMPORT_MSG_FUN(idn);

/**
 * @function: rst
 * @description: 软复位
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t rst(myCmd_Info_Type info)
{
    my_rst();
    return MS_EOK;
}
IMPORT_MSG_FUN(rst);

/**
 * @function: ver
 * @description: 查询版本
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t ver(myCmd_Info_Type info)
{
    my_ver();
    return MS_EOK;
}
IMPORT_MSG_FUN(ver);

//////////////////////////////////////////读取命令/////////////////////////////////////////////

/**
 * @function: get_wav
 * @description: 读取当前波长
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t get_wav(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(get_wav);

/**
 * @function: get_pow
 * @description: 读取当前波长的功率
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t get_pow(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(get_pow);

/**
 * @function: get_vol
 * @description: 获取电压值
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t get_vol(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(get_vol);


/**
 * @function: get_his
 * @description: 获取历史记录
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t get_his(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(get_his);

//////////////////////////////////////////设置命令/////////////////////////////////////////////

/**
 * @function: set_wav
 * @description: 设置当前波长
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t set_wav(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(set_wav);

/**
 * @function: set_pow
 * @description: 设置当前功率（整偏）
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t set_pow(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(set_pow);

/**
 * @function: set_lin_res
 * @description: 清除线性系数
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t set_lin_res(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(set_lin_res);

/**
 * @function: set_coe_res
 * @description: 清除波长系数
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t set_coe_res(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(set_coe_res);


//////////////////////////////////////////校准命令/////////////////////////////////////////////
/**
 * @function: cal_sta
 * @description: 开始校准
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t cal_sta(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_sta);


/**
 * @function: cal_sto
 * @description: 结束校准
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t cal_sto(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_sto);

/**
 * @function: cal_sav
 * @description: 保存校准值
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t cal_sav(myCmd_Info_Type info)
{
    MSG_OUTPUT("ok\n");
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_sav);


/**
 * @function: cal_lev
 * @description: 校准模式校准
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t cal_lev(myCmd_Info_Type info)
{
    MSG_OUTPUT("ok\n");
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_lev);

/**
 * @brief 校准点,具有确定性
 * @param
 * @return
 */
static uint8_t cal_poi_pow(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_poi_pow);


/**
 * @function: cal_clr
 * @brief: 清除全部校准数据
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t cal_clr(myCmd_Info_Type info)
{
    MSG_OUTPUT("ok\n");
    return MS_EOK;
}
IMPORT_MSG_FUN(cal_clr);
//////////////////////////////////////////系统命令/////////////////////////////////////////////

/**
 * @function: sys_upg
 * @description: 系统升级
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t sys_upg(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(sys_upg);

/**
 * @function: sys_off
 * @description: 自动关机
 * @param {*}
 * @return {*}
 * @author: lzc
 */
static uint8_t sys_off(myCmd_Info_Type info)
{
    return MS_EOK;
}
IMPORT_MSG_FUN(sys_off);
